From 8db66fa81bbfab66a497c8bc3fd1716d0bf9f563 Mon Sep 17 00:00:00 2001 From: robertl Date: Mon, 28 Apr 2003 13:45:04 +0000 Subject: [PATCH] Add position filter for radius, courtesy Alex Mottram. --- gpsbabel/README | 17 +++++++++ gpsbabel/filter_vecs.c | 6 ++++ gpsbabel/position.c | 79 ++++++++++++++++++++++++++++++++++++++++-- gpsbabel/testo | 9 +++++ 4 files changed, 108 insertions(+), 3 deletions(-) diff --git a/gpsbabel/README b/gpsbabel/README index 0db94a679..a5e64c4a1 100644 --- a/gpsbabel/README +++ b/gpsbabel/README @@ -336,6 +336,23 @@ DATA FILTERS leaving just one. + RADIUS + + The radius filter is designed to include points based on their + proximity to a central point. Distances and the central point + are declared on the command line by passing the distance=X.XX, + lat=X.XX, and lon=X.XX options to the filter. Distance options + may be expressed in miles (distance=3M) or kilometers (distance=3K). + The default is zero miles. + + For example: + + gpsbabel -i geo -f 1.loc -x radius,distance=1.5M,lat=30.0,lon=-90.0 \ + -o mapsend -F 2.wpt + + would include only points within 1.5 miles of N30.000 W90.000 + + DUPLICATE The duplicate filter is designed to remove duplicate points based diff --git a/gpsbabel/filter_vecs.c b/gpsbabel/filter_vecs.c index 4dc76b0de..3f87a8700 100644 --- a/gpsbabel/filter_vecs.c +++ b/gpsbabel/filter_vecs.c @@ -29,6 +29,7 @@ typedef struct { } fl_vecs_t; extern filter_vecs_t position_vecs; +extern filter_vecs_t radius_vecs; extern filter_vecs_t duplicate_vecs; static @@ -38,6 +39,11 @@ fl_vecs_t filter_vec_list[] = { "position", "Remove Points Within Distance", }, + { + &radius_vecs, + "radius", + "Include Only Points Within Radius", + }, { &duplicate_vecs, "duplicate", diff --git a/gpsbabel/position.c b/gpsbabel/position.c index 36cceb54f..3c1b7a019 100644 --- a/gpsbabel/position.c +++ b/gpsbabel/position.c @@ -1,5 +1,5 @@ /* - Distance Between Points Filter + Distance Between Points Filter(s) Copyright (C) 2002 Robert Lipe, robertlipe@usa.net @@ -30,6 +30,10 @@ extern queue waypt_head; static double pos_dist; static char *distopt; +static char *latopt; +static char *lonopt; + +waypoint * home_pos; static arglist_t position_args[] = { @@ -37,6 +41,14 @@ arglist_t position_args[] = { {0, 0, 0} }; +static +arglist_t radius_args[] = { + {"lat", &latopt, "Latitude for center point (D.DDDDD)"}, + {"lon", &lonopt, "Longitude for center point (D.DDDDD)"}, + {"distance", &distopt, "Maximum distance from center"}, + {0, 0, 0} +}; + static double gc_distance(double lat1, double lon1, double lat2, double lon2) { @@ -81,7 +93,7 @@ position_comp(const void * a, const void * b) return(0); } -void +void position_process(void) { queue * elem, * tmp; @@ -111,7 +123,7 @@ position_process(void) /* convert radians to integer feet */ dist = (int)((((dist * 180.0 * 60.0) / M_PI) * 1.1516) * 5280.0); - if (dist <= pos_dist) { + if (dist <= pos_dist) { waypt_del(comp[i]); waypt_free(comp[i]); } @@ -141,9 +153,70 @@ void position_deinit(void) { } +void +radius_process(void) +{ + queue * elem, * tmp; + waypoint * waypointp; + double dist; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint *)elem; + + dist = gc_distance(waypointp->position.latitude.degrees, + waypointp->position.longitude.degrees, + home_pos->position.latitude.degrees, + home_pos->position.longitude.degrees); + + /* convert radians to float point statute miles */ + dist = (((dist * 180.0 * 60.0) / M_PI) * 1.1516); + + if (dist >= pos_dist) { + waypt_del(waypointp); + waypt_free(waypointp); + } + } +} + +void +radius_init(const char *args) { + char *fm; + + pos_dist = 0; + + if (distopt) { + pos_dist = strtod(distopt, &fm); + + if ((*fm == 'k') || (*fm == 'K')) { + /* distance is kilometers, convert to feet */ + pos_dist *= .6214; + } + } + + home_pos = xcalloc(sizeof(*home_pos), 1); + + if (latopt) + home_pos->position.latitude.degrees = atof(latopt); + if (lonopt) + home_pos->position.longitude.degrees = atof(lonopt); +} + +void +radius_deinit(void) { + if (home_pos) + xfree(home_pos); +} + filter_vecs_t position_vecs = { position_init, position_process, position_deinit, position_args }; + +filter_vecs_t radius_vecs = { + radius_init, + radius_process, + radius_deinit, + radius_args +}; diff --git a/gpsbabel/testo b/gpsbabel/testo index 2ff9ba643..4c218bb8f 100755 --- a/gpsbabel/testo +++ b/gpsbabel/testo @@ -239,6 +239,15 @@ ${PNAME} -i geo -f geocaching.loc -f geocaching.loc -x position,distance=5f \ -o csv -F ${TMPDIR}/filterpos.csv2 compare ${TMPDIR}/filterpos.csv1 ${TMPDIR}/filterpos.csv2 +# +# Radius filter +# +rm -f ${TMPDIR}/radius.csv +${PNAME} -i geo -f geocaching.loc \ + -x radius,lat=35.9720,lon=-87.1347,distance=14.7 \ + -o csv -F ${TMPDIR}/radius.csv +compare ${TMPDIR}/radius.csv reference/ + # # magellan SD card waypoint / route format # -- 2.30.2